package com.example.war;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.egl.EGLConfig;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.PointF;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;

import net.rbgrn.android.glwallpaperservice.*;

public class MyRenderer implements GLWallpaperService.Renderer {
    private static final String TAG = "zzzz";
    private Soldier mSoldier;
    private Meteors mMeteors;
    private Stars mStars;
    private Hole mHole;
    private Quad mBgQuad;
    private Quad mBulletHoleQuad;
    private Context mContext;
    private Point mScrSize;
    private int mBgImgWidth;
    private int mBgImgHeight;
    private float mBgTexWidth;
    private float mBgTexWidthRatio;
    private float mBgTexX;
    private long mDownTime;
    private boolean mIsTapScrren = false;
    private PointF mDownPoint = new PointF();
    private PointF mLastPoint = new PointF();
    
    private static final int TAP_SCREEN_TIME_OUT = 200;
    private static final int TAP_SCREEN_ANIM_DURATION = 3500;
    private static final int MIN_MOVE_DIST = 5;
    
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            mIsTapScrren = false;
        }
    };
    
    public MyRenderer(Context context) {
        mContext = context;
        mScrSize = Utils.getScreenSize(context);
        Log.d("xxxx","=== mScrSize:"+mScrSize.x+", "+mScrSize.y);
    }
    
    private void drawBackground(GL10 gl) {
        mBgQuad.setTexCoods(mBgTexX/mBgImgWidth, 0, mBgTexWidthRatio, 1.0f);
        mBgQuad.draw(gl, 0, 0, 0, 0);
    }

    public void onDrawFrame(GL10 gl) {
        // Your rendering code goes here
        gl.glClearColor(0.14f, 0.15f, 0.33f, 1f);
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glTranslatef(0, 0, -20f);
        drawBackground(gl);

        mStars.draw(gl);
        mMeteors.draw(gl);
        
        mSoldier.draw(gl);
        
        if (mIsTapScrren) {
            //mBulletHoleQuad.draw(gl, 0, mDownPoint.x - mScrSize.x/2, mScrSize.y/2 - mDownPoint.y, 0, true);
            mHole.draw(gl, mDownPoint.x - mScrSize.x/2, mScrSize.y/2 - mDownPoint.y);
        }
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        if (height == 0) { // Prevent A Divide By Zero By
            height = 1; // Making Height Equal One
        }

        gl.glViewport(0, 0, width, height); // Reset The Current Viewport
        gl.glMatrixMode(GL10.GL_PROJECTION); // Select The Projection Matrix
        gl.glLoadIdentity(); // Reset The Projection Matrix

        // Calculate The Aspect Ratio Of The Window
        //GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f, 100.0f);
        gl.glOrthof(-width/2, width/2, -height/2, height/2, 10.0f, 500.0f);

        gl.glMatrixMode(GL10.GL_MODELVIEW); // Select The Modelview Matrix
        gl.glLoadIdentity(); // Reset The Modelview Matrix
        
        Log.d("xiaobo","onSurfaceChanged");
    }

    /**
     * Called when the engine is destroyed. Do any necessary clean up because
     * at this point your renderer instance is now done for.
     */
    public void release() {
        
    }
    
    boolean isInitialized = false;

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        if(isInitialized) {
            return;
        } else {
            isInitialized = true;
        }
        // Settings
        gl.glDisable(GL10.GL_DITHER); // Disable dithering

        // Really Nice Perspective Calculations
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
        mBgQuad = new Quad(false);
        Bitmap bgBitmap = Utils.loadRawImage(mContext.getResources(), R.raw.bg);
        Point scrSize = Utils.getScreenSize(mContext);
        mBgImgWidth = bgBitmap.getWidth();
        mBgImgHeight = bgBitmap.getHeight();
        float scrRatio = mScrSize.x * 1.0f / mScrSize.y;
        mBgTexWidth = mBgImgHeight * scrRatio;
        mBgTexWidthRatio = mBgTexWidth / mBgImgWidth;
        mBgTexX = (mBgImgWidth - mBgTexWidth) / 2.0f;
        mBgQuad.setTexture(gl, bgBitmap, false);
        mBgQuad.setSize(scrSize.x, scrSize.y);
        bgBitmap.recycle();
        
        mBulletHoleQuad = new Quad(false);
        Bitmap bulletHoleBitmap = Utils.loadRawImage(mContext.getResources(), R.raw.hole);
        mBulletHoleQuad.setSize(bulletHoleBitmap.getWidth(), bulletHoleBitmap.getHeight());
        mBulletHoleQuad.setTexture(gl, bulletHoleBitmap, false);
        bulletHoleBitmap.recycle();

        mSoldier = new Soldier(mContext, gl);
        mMeteors = new Meteors(mContext, gl);
        mStars = new Stars(mContext, gl);
        mHole = new Hole(mContext, gl);
        Log.d("xiaobo","onSurfaceCreated", new Throwable());
    }
    
    public void onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            mDownPoint.x = mLastPoint.x = event.getX();
            mDownPoint.y = mLastPoint.y = event.getY();
            mDownTime = System.currentTimeMillis();
            break;
        case MotionEvent.ACTION_MOVE:
            float xOff = x - mLastPoint.x;
            if (Math.abs(xOff) > MIN_MOVE_DIST) {
                mBgTexX += xOff*0.4;
                if (mBgTexX > mBgImgWidth - mBgTexWidth) {
                    mBgTexX = mBgImgWidth - mBgTexWidth;
                } else if (mBgTexX < 0) {
                    mBgTexX = 0;
                }
                mLastPoint.x = event.getX();
                mLastPoint.y = event.getY();
            }
            break;
        case MotionEvent.ACTION_UP:
            long currentTime = System.currentTimeMillis();
            if (Math.abs(x - mDownPoint.x) < 10 &&
                Math.abs(y - mDownPoint.y) < 10 &&
                currentTime - mDownTime < TAP_SCREEN_TIME_OUT) {
                mIsTapScrren = true;
                mSoldier.startDither(currentTime, 500);
                mHole.reset(currentTime, TAP_SCREEN_ANIM_DURATION);
                mHandler.removeMessages(0);
                mHandler.sendMessageDelayed(Message.obtain(mHandler, 0), TAP_SCREEN_ANIM_DURATION);
//                mHandler.postDelayed(new Runnable() {
//                    @Override
//                    public void run() {
//                        mIsTapScrren = false;
//                    }
//                }, TAP_SCREEN_ANIM_DURATION);
            }
            break;

        default:
            break;
        }
    }
}